package com.skyjing.askit.view.roundimageview

import android.content.res.ColorStateList
import android.content.res.Resources
import android.graphics.Bitmap
import android.util.DisplayMetrics
import android.util.TypedValue
import android.widget.ImageView.ScaleType
import com.skyjing.askit.view.roundimageview.RoundedDrawable.Companion.fromBitmap

class RoundedTransformationBuilder {
    private val mDisplayMetrics: DisplayMetrics
    private var mCornerRadius = 0f
    private var mOval = false
    private var mBorderWidth = 0f
    private var mBorderColor = ColorStateList
        .valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR)
    private var mScaleType = ScaleType.FIT_CENTER
    fun scaleType(scaleType: ScaleType): RoundedTransformationBuilder {
        mScaleType = scaleType
        return this
    }

    /**
     * set corner radius in px
     */
    fun cornerRadius(radiusPx: Float): RoundedTransformationBuilder {
        mCornerRadius = radiusPx
        return this
    }

    /**
     * set corner radius in dip
     */
    fun cornerRadiusDp(radiusDp: Float): RoundedTransformationBuilder {
        mCornerRadius = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            radiusDp, mDisplayMetrics
        )
        return this
    }

    /**
     * set border width in px
     */
    fun borderWidth(widthPx: Float): RoundedTransformationBuilder {
        mBorderWidth = widthPx
        return this
    }

    /**
     * set border width in dip
     */
    fun borderWidthDp(widthDp: Float): RoundedTransformationBuilder {
        mBorderWidth = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            widthDp, mDisplayMetrics
        )
        return this
    }

    /**
     * set border color
     */
    fun borderColor(color: Int): RoundedTransformationBuilder {
        mBorderColor = ColorStateList.valueOf(color)
        return this
    }

    fun borderColor(colors: ColorStateList): RoundedTransformationBuilder {
        mBorderColor = colors
        return this
    }

    fun oval(oval: Boolean): RoundedTransformationBuilder {
        mOval = oval
        return this
    }

    fun build(): Transformation {
        return object :
            Transformation {
            override fun transform(source: Bitmap): Bitmap? {
                val transformed =
                    fromBitmap(source)?.setScaleType(mScaleType)?.setCornerRadius(mCornerRadius)
                        ?.setBorderWidth(mBorderWidth)?.setBorderColor(mBorderColor)?.setOval(mOval)
                        ?.toBitmap()
                if (source != transformed) {
                    source.recycle()
                }
                return transformed
            }

            override fun key(): String {
                return ("r:" + mCornerRadius + "b:" + mBorderWidth + "c:"
                        + mBorderColor + "o:" + mOval)
            }
        }
    }

    interface Transformation {
        /**
         * Transform the source bitmap into a new bitmap. If you create a new bitmap
         * instance, you must call [Bitmap.recycle] on
         * `source`. You may return the original if no transformation is
         * required.
         */
        fun transform(source: Bitmap): Bitmap?

        /**
         * Returns a unique key for the transformation, used for caching purposes.
         * If the transformation has parameters (e.g. size, scale factor, etc) then
         * these should be part of the key.
         */
        fun key(): String
    }

    init {
        mDisplayMetrics = Resources.getSystem().displayMetrics
    }
}